﻿using System;
using System.Collections.Generic;
using RotovapPlatform.Domain.Business.Machine.Enums;

namespace RotovapPlatform.Domain.Business.Machine.Entities
{
	/// <summary>
	/// 设备实体类
	/// </summary>
	public class Device
	{
		/// <summary>
		/// 设备ID
		/// </summary>
		public Guid DeviceId { get; set; } = Guid.NewGuid();

		/// <summary>
		/// 设备名称
		/// </summary>
		public string DeviceName { get; set; }

		/// <summary>
		/// 设备型号
		/// </summary>
		public string DeviceModel { get; set; }

		/// <summary>
		/// 设备序列号
		/// </summary>
		public string SerialNumber { get; set; }

		/// <summary>
		/// 设备模式
		/// </summary>
		public DeviceEnums.DeviceMode Mode { get; set; } = DeviceEnums.DeviceMode.Manual;

		/// <summary>
		/// 设备状态
		/// </summary>
		public DeviceEnums.DeviceStatus Status { get; set; } = DeviceEnums.DeviceStatus.Idle;

		/// <summary>
		/// 当前运行的实验ID
		/// </summary>
		public Guid? CurrentExperimentId { get; set; }

		/// <summary>
		/// 当前运行的实验组ID
		/// </summary>
		public Guid? CurrentExperimentGroupId { get; set; }

		/// <summary>
		/// 当前主步骤
		/// </summary>
		public DeviceEnums.MainStep CurrentMainStep { get; set; } = DeviceEnums.MainStep.None;

		/// <summary>
		/// 当前分步骤
		/// </summary>
		public object CurrentSubStep { get; set; }

		/// <summary>
		/// 当前同步步骤列表
		/// </summary>
		public List<DeviceEnums.SynchronousStep> CurrentSynchronousSteps { get; set; } = new List<DeviceEnums.SynchronousStep>();

		/// <summary>
		/// 设备参数
		/// </summary>
		public DeviceParameters Parameters { get; set; } = new DeviceParameters();

		/// <summary>
		/// 设备运行时间信息
		/// </summary>
		public DeviceTimeInfo TimeInfo { get; set; } = new DeviceTimeInfo();

		/// <summary>
		/// 机械手状态
		/// </summary>
		public DeviceEnums.RobotArmStatus RobotArmStatus { get; set; } = DeviceEnums.RobotArmStatus.Idle;

		/// <summary>
		/// 机械手位置
		/// </summary>
		public string RobotArmPosition { get; set; } = "Home";

		/// <summary>
		/// 错误代码
		/// </summary>
		public int? ErrorCode { get; set; }

		/// <summary>
		/// 错误信息
		/// </summary>
		public string ErrorMessage { get; set; }

		/// <summary>
		/// 设备组件列表
		/// </summary>
		public List<DeviceComponent> Components { get; set; } = new List<DeviceComponent>();

		/// <summary>
		/// 设备是否在线
		/// </summary>
		public bool IsOnline { get; set; } = true;

		/// <summary>
		/// 设备最后更新时间
		/// </summary>
		public DateTime LastUpdateTime { get; set; } = DateTime.Now;

		/// <summary>
		/// 获取当前分步骤的强类型引用
		/// </summary>
		/// <typeparam name="T">分步骤类型</typeparam>
		/// <returns>分步骤</returns>
		public T GetCurrentSubStep<T>() where T : Enum
		{
			return (T)CurrentSubStep;
		}

		/// <summary>
		/// 设置当前分步骤
		/// </summary>
		/// <typeparam name="T">分步骤类型</typeparam>
		/// <param name="subStep">分步骤</param>
		public void SetCurrentSubStep<T>(T subStep) where T : Enum
		{
			CurrentSubStep = subStep;
		}

		/// <summary>
		/// 添加同步步骤
		/// </summary>
		/// <param name="step">同步步骤</param>
		public void AddSynchronousStep(DeviceEnums.SynchronousStep step)
		{
			if (!CurrentSynchronousSteps.Contains(step))
			{
				CurrentSynchronousSteps.Add(step);
			}
		}

		/// <summary>
		/// 移除同步步骤
		/// </summary>
		/// <param name="step">同步步骤</param>
		public void RemoveSynchronousStep(DeviceEnums.SynchronousStep step)
		{
			CurrentSynchronousSteps.Remove(step);
		}

		/// <summary>
		/// 清空同步步骤
		/// </summary>
		public void ClearSynchronousSteps()
		{
			CurrentSynchronousSteps.Clear();
		}

		/// <summary>
		/// 添加设备组件
		/// </summary>
		/// <param name="component">设备组件</param>
		public void AddComponent(DeviceComponent component)
		{
			Components.Add(component);
		}

		/// <summary>
		/// 获取设备组件
		/// </summary>
		/// <param name="componentType">组件类型</param>
		/// <returns>设备组件</returns>
		public DeviceComponent GetComponent(DeviceEnums.DeviceComponentType componentType)
		{
			return Components.Find(c => c.ComponentType == componentType);
		}

		/// <summary>
		/// 更新设备状态
		/// </summary>
		/// <param name="status">设备状态</param>
		public void UpdateStatus(DeviceEnums.DeviceStatus status)
		{
			Status = status;
			LastUpdateTime = DateTime.Now;
		}

		/// <summary>
		/// 更新设备模式
		/// </summary>
		/// <param name="mode">设备模式</param>
		public void UpdateMode(DeviceEnums.DeviceMode mode)
		{
			Mode = mode;
			LastUpdateTime = DateTime.Now;
		}

		/// <summary>
		/// 更新主步骤
		/// </summary>
		/// <param name="mainStep">主步骤</param>
		public void UpdateMainStep(DeviceEnums.MainStep mainStep)
		{
			CurrentMainStep = mainStep;
			LastUpdateTime = DateTime.Now;

			// 重置分步骤
			switch (mainStep)
			{
				case DeviceEnums.MainStep.MaterialPreparation:
					SetCurrentSubStep(DeviceEnums.MaterialPreparationSubStep.Initialize);
					break;
				case DeviceEnums.MainStep.FlaskDocking:
					SetCurrentSubStep(DeviceEnums.FlaskDockingSubStep.Initialize);
					break;
				case DeviceEnums.MainStep.MaterialTransfer:
					SetCurrentSubStep(DeviceEnums.MaterialTransferSubStep.Initialize);
					break;
				case DeviceEnums.MainStep.RotovapProcess:
					SetCurrentSubStep(DeviceEnums.RotovapProcessSubStep.Initialize);
					break;
				case DeviceEnums.MainStep.ProductCollection:
					SetCurrentSubStep(DeviceEnums.ProductCollectionSubStep.Initialize);
					break;
				case DeviceEnums.MainStep.ResidueHandling:
					SetCurrentSubStep(DeviceEnums.ResidueHandlingSubStep.Initialize);
					break;
				case DeviceEnums.MainStep.SystemCleaning:
					SetCurrentSubStep(DeviceEnums.SystemCleaningSubStep.Initialize);
					break;
				default:
					CurrentSubStep = null;
					break;
			}
		}

		/// <summary>
		/// 设置错误信息
		/// </summary>
		/// <param name="errorCode">错误代码</param>
		/// <param name="errorMessage">错误信息</param>
		public void SetError(int errorCode, string errorMessage)
		{
			ErrorCode = errorCode;
			ErrorMessage = errorMessage;
			Status = DeviceEnums.DeviceStatus.Error;
			LastUpdateTime = DateTime.Now;
		}

		/// <summary>
		/// 清除错误信息
		/// </summary>
		public void ClearError()
		{
			ErrorCode = null;
			ErrorMessage = null;
			LastUpdateTime = DateTime.Now;
		}
	}

	/// <summary>
	/// 设备参数
	/// </summary>
	public class DeviceParameters
	{
		/// <summary>
		/// 油浴温度
		/// </summary>
		public double OilBathTemperature { get; set; }

		/// <summary>
		/// 油浴目标温度
		/// </summary>
		public double OilBathTargetTemperature { get; set; }

		/// <summary>
		/// 冷凝温度
		/// </summary>
		public double CondensationTemperature { get; set; }

		/// <summary>
		/// 冷凝目标温度
		/// </summary>
		public double CondensationTargetTemperature { get; set; }

		/// <summary>
		/// 旋转速度
		/// </summary>
		public double RotationSpeed { get; set; }

		/// <summary>
		/// 旋转目标速度
		/// </summary>
		public double RotationTargetSpeed { get; set; }

		/// <summary>
		/// 真空度
		/// </summary>
		public double Vacuum { get; set; }

		/// <summary>
		/// 真空目标值
		/// </summary>
		public double VacuumTarget { get; set; }

		/// <summary>
		/// 液位
		/// </summary>
		public double LiquidLevel { get; set; }

		/// <summary>
		/// 流量
		/// </summary>
		public double FlowRate { get; set; }

		/// <summary>
		/// 压力
		/// </summary>
		public double Pressure { get; set; }

		/// <summary>
		/// 其他参数
		/// </summary>
		public Dictionary<string, object> AdditionalParameters { get; set; } = new Dictionary<string, object>();
	}

	/// <summary>
	/// 设备运行时间信息
	/// </summary>
	public class DeviceTimeInfo
	{
		/// <summary>
		/// 总运行时间（小时）
		/// </summary>
		public double TotalRunTimeHours { get; set; }

		/// <summary>
		/// 当前实验开始时间
		/// </summary>
		public DateTime? CurrentExperimentStartTime { get; set; }

		/// <summary>
		/// 当前步骤开始时间
		/// </summary>
		public DateTime? CurrentStepStartTime { get; set; }

		/// <summary>
		/// 当前分步骤开始时间
		/// </summary>
		public DateTime? CurrentSubStepStartTime { get; set; }

		/// <summary>
		/// 上次维护时间
		/// </summary>
		public DateTime? LastMaintenanceTime { get; set; }

		/// <summary>
		/// 上次校准时间
		/// </summary>
		public DateTime? LastCalibrationTime { get; set; }

		/// <summary>
		/// 获取当前实验运行时间（分钟）
		/// </summary>
		public double CurrentExperimentRunTimeMinutes
		{
			get
			{
				if (CurrentExperimentStartTime.HasValue)
				{
					return (DateTime.Now - CurrentExperimentStartTime.Value).TotalMinutes;
				}
				return 0;
			}
		}

		/// <summary>
		/// 获取当前步骤运行时间（分钟）
		/// </summary>
		public double CurrentStepRunTimeMinutes
		{
			get
			{
				if (CurrentStepStartTime.HasValue)
				{
					return (DateTime.Now - CurrentStepStartTime.Value).TotalMinutes;
				}
				return 0;
			}
		}

		/// <summary>
		/// 获取当前分步骤运行时间（秒）
		/// </summary>
		public double CurrentSubStepRunTimeSeconds
		{
			get
			{
				if (CurrentSubStepStartTime.HasValue)
				{
					return (DateTime.Now - CurrentSubStepStartTime.Value).TotalSeconds;
				}
				return 0;
			}
		}

		/// <summary>
		/// 更新当前实验开始时间
		/// </summary>
		public void UpdateCurrentExperimentStartTime()
		{
			CurrentExperimentStartTime = DateTime.Now;
		}

		/// <summary>
		/// 更新当前步骤开始时间
		/// </summary>
		public void UpdateCurrentStepStartTime()
		{
			CurrentStepStartTime = DateTime.Now;
		}

		/// <summary>
		/// 更新当前分步骤开始时间
		/// </summary>
		public void UpdateCurrentSubStepStartTime()
		{
			CurrentSubStepStartTime = DateTime.Now;
		}

		/// <summary>
		/// 更新上次维护时间
		/// </summary>
		public void UpdateLastMaintenanceTime()
		{
			LastMaintenanceTime = DateTime.Now;
		}

		/// <summary>
		/// 更新上次校准时间
		/// </summary>
		public void UpdateLastCalibrationTime()
		{
			LastCalibrationTime = DateTime.Now;
		}
	}

	/// <summary>
	/// 设备组件
	/// </summary>
	public class DeviceComponent
	{
		/// <summary>
		/// 组件ID
		/// </summary>
		public Guid ComponentId { get; set; } = Guid.NewGuid();

		/// <summary>
		/// 组件类型
		/// </summary>
		public DeviceEnums.DeviceComponentType ComponentType { get; set; }

		/// <summary>
		/// 组件名称
		/// </summary>
		public string Name { get; set; }

		/// <summary>
		/// 组件描述
		/// </summary>
		public string Description { get; set; }

		/// <summary>
		/// 组件状态
		/// </summary>
		public string Status { get; set; } = "正常";

		/// <summary>
		/// 组件是否在线
		/// </summary>
		public bool IsOnline { get; set; } = true;

		/// <summary>
		/// 组件参数
		/// </summary>
		public Dictionary<string, object> Parameters { get; set; } = new Dictionary<string, object>();

		/// <summary>
		/// 组件错误信息
		/// </summary>
		public string ErrorMessage { get; set; }

		/// <summary>
		/// 组件最后更新时间
		/// </summary>
		public DateTime LastUpdateTime { get; set; } = DateTime.Now;

		/// <summary>
		/// 设置组件参数
		/// </summary>
		/// <param name="key">参数名</param>
		/// <param name="value">参数值</param>
		public void SetParameter(string key, object value)
		{
			Parameters[key] = value;
			LastUpdateTime = DateTime.Now;
		}

		/// <summary>
		/// 获取组件参数
		/// </summary>
		/// <typeparam name="T">参数类型</typeparam>
		/// <param name="key">参数名</param>
		/// <param name="defaultValue">默认值</param>
		/// <returns>参数值</returns>
		public T GetParameter<T>(string key, T defaultValue = default)
		{
			if (Parameters.TryGetValue(key, out var value) && value is T typedValue)
			{
				return typedValue;
			}
			return defaultValue;
		}

		/// <summary>
		/// 设置组件状态
		/// </summary>
		/// <param name="status">状态</param>
		public void SetStatus(string status)
		{
			Status = status;
			LastUpdateTime = DateTime.Now;
		}

		/// <summary>
		/// 设置组件错误信息
		/// </summary>
		/// <param name="errorMessage">错误信息</param>
		public void SetError(string errorMessage)
		{
			ErrorMessage = errorMessage;
			Status = "错误";
			LastUpdateTime = DateTime.Now;
		}

		/// <summary>
		/// 清除组件错误信息
		/// </summary>
		public void ClearError()
		{
			ErrorMessage = null;
			Status = "正常";
			LastUpdateTime = DateTime.Now;
		}
	}
}